﻿#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System;
using System.Web;
using System.Web.UI;
using NeoPatterns.Core.Registry;
using NeoPatterns.Setup;

namespace NeoPatterns.Patterns.IoC
{
    /// <summary>
    /// Module version of dependency injection pattern for web sites
    /// </summary>
    public class DependencyInjectionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            WebConfiguration.Load();
            context.PreRequestHandlerExecute += PreRequestHandlerExecute;
        }

        /// <summary>
        /// Returns the page type for an ASPX page
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        protected virtual Type GetPageTypeForASPX(object page)
        {
            if (page is Page)
            {
                // ASP.NET 2.0 inherits the current page
                return page.GetType().BaseType;
            }
            return null;
        }

        /// <summary>
        /// Returns the page type for an ASCX control
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        protected virtual Type GetPageTypeForASCX(object page)
        {
            // TODO: find ASCX object type
            return null;
        }

        /// <summary>
        /// Returns the page type for an ASMX web service
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        protected virtual Type GetPageTypeForASMX(object page)
        {
            // TODO: find ASMX web service type (and an idea on how to do this)
            return null;
        }

        /// <summary>
        /// Guesses the underlying object type
        /// </summary>
        /// <param name="handler"></param>
        /// <returns></returns>
        protected virtual Type GetPageType(object handler)
        {
            // the whole thing is staged in different parts, 
            // each part handling only is type
            Type pageType;
            // pages
            pageType = GetPageTypeForASPX(handler);
            if (pageType != null)
                return pageType;
            // controls
            pageType = GetPageTypeForASCX(handler);
            if (pageType != null)
                return pageType;
            // web services
            pageType = GetPageTypeForASMX(handler);
            if (pageType != null)
                return pageType;
            return null;
        }

        /// <summary>
        /// Called after the page is created
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void PreRequestHandlerExecute(object sender, EventArgs e)
        {
            var application = (HttpApplication)sender;
            var page = application.Context.Handler;
            var pageType = GetPageType(page);
            if (pageType != null)
                Application.ObjectRegistry.Initialize(page, pageType);
        }

        public void Dispose()
        {
        }
    }
}
